/*
 * chapter_17.cpp
 *
 *  Created on: 2020年12月15日
 *      Author: san
 */

#include <iostream>
#include <tuple>
#include <bitset>
#include <random>
#include <iomanip>
#include <fstream>

#include "common_tools.h"
//#include "common_tools.h"

#include "MyVec.h"
#include "MyVec.h"


void t17_1()
{
	auto tp = std::make_tuple(1,2,3,4,5,6,7);
	std::tuple<int, int, int> itp{10,20,30};
}

void t17_10()
{
	std::bitset<32> b(27);
	std::cout << b;
}

void t17_28()
{
	std::uniform_int_distribution<unsigned> u;
	std::default_random_engine e;
	for (unsigned i = 0; i < 10; ++i)
	{
		std::cout << e() << " ";
	}
	std::cout << std::endl;
}

void t17_29()
{
	unsigned seed;
	std::cout << "请输入随机数种子： ";
	std::uniform_int_distribution<unsigned> u;
	std::default_random_engine e(seed);
	while (std::cin >> seed)
	{
		for (unsigned i = 0; i < 10; ++i)
		{
			std::cout << e() << " ";
		}
		std::cout << std::endl;
	}
}

void t17_30()
{
	auto random_n = san::get_random(0, 100);
	for (unsigned i = 0; i < 10; ++i)
	{
		std::cout << random_n[i]  << " ";
	}
}

void t17_35()
{
	std::cout <<"default format: " << sqrt(2.0) << '\n'
		<< "scientific: " << std::scientific << sqrt(2.0) << '\n'
		<< "fixed decimal: " << std::fixed << sqrt(2.0) << '\n'
		<< "hexidecimal: " << std::uppercase << std::hexfloat << sqrt(2.0) << '\n'
		<< "use defaults: " << std::defaultfloat << sqrt(2.0)
		<< "\n\n";
}

void t17_36()
{
	std::cout << std::left << std::setw(16) <<"default format: " << std::right << std::setw(25) << sqrt(2.0) << '\n'
		<< std::left << std::setw(16) << "scientific: " << std::scientific << std::right << std::setw(25) << sqrt(2.0) << '\n'
		<< std::left << std::setw(16) << "fixed decimal: " << std::fixed << std::right << std::setw(25) << sqrt(2.0) << '\n'
		<< std::left << std::setw(16) << "hexidecimal: " << std::uppercase << std::hexfloat << std::right << std::setw(25) << sqrt(2.0) << '\n'
		<< std::left << std::setw(16) << "use defaults: " << std::defaultfloat << std::right << std::setw(25) << sqrt(2.0)
		<< "\n\n";
}

int t17_39()
{
	std::fstream fs("/home/san/eclipse-workspace/CppPrimer/file/alibaba.txt",
			std::fstream::ate | std::fstream::in | std::fstream::out);
	if (!fs)
	{
		std::cerr << "Unable to open file";
		return EXIT_FAILURE;
	}
	// ate模式打开，一开始就定位到文件末尾
	auto end_mark = fs.tellg();
	fs.seekg(0, std::fstream::beg);  // 定位文件开始
	size_t cnt = 0;  // 记录读取的字节数
	std::string line;
	while (fs && fs.tellg() != end_mark && std::getline(fs, line))
	{
		cnt += line.size() + 1;
		auto mark = fs.tellg();  // 更新读取位置
		fs.seekp(0, std::fstream::end);  // 将写标记定位到文件末尾
		fs << cnt << std::flush; // 向文件末尾写入偏移量
		if (mark != end_mark) fs << " " << std::flush;
		fs.seekg(mark);  // 恢复文件指针位置
	}
	fs.seekp(0, std::fstream::end);  // 定位到文件末尾
	fs << std::endl << std::flush;
	fs << "By san" << std::flush;
	fs.close();
	fs.clear();
	std::cerr << "OK" << std::endl;
	std::cerr << "fs closed!" << std::endl;
}

int main17()
{
	// tuple
	t17_1();

	// bitset 二进制和位运算
	t17_10();

	// 正则表达式（跳过）

	// 随机数
	t17_28();  // 随机生成随机数
//	t17_29();  // 用户指定种子
	t17_30();  // 表示函数允许返回的最大值和最小值

	// IO库 格式控制
	t17_35();
	t17_36();

	std::cout << "-----------------未格式化的输入输出操作-------------------" << std::endl;
//	std::ifstream fs("/home/san/eclipse-workspace/CppPrimer/file/alibaba.txt");
//	char tmp[150];  // sink的size过小会 *** stack smashing detected ***: terminated
//	fs.getline(tmp, 105, '\n');  // 如果size过小，流会broken
//	std::cout << tmp << std::endl;
//	std::cout << fs.gcount() << std::endl;
//
//	if (!fs)
//		std::cerr << "fs is broken" << std::endl;
//
//	fs.getline(tmp, 150, '\n');
//	std::cout << tmp << std::endl;
//	std::cout << fs.gcount() << std::endl;
//	std::cout << std::boolalpha << (fs.rdstate() == std::ios_base::failbit) << std::endl;
//	std::cout << std::ios_base::goodbit << std::endl;
//	std::cout << std::ios_base::badbit << std::endl;
//	std::cout << std::ios_base::failbit << std::endl;
//	std::cout << std::ios_base::eofbit << std::endl;
//	fs.close();
	//https://en.cppreference.com/w/cpp/io/ios_base/iostate

	std::cout << "----------------流随机访问------------------" << std::endl;
	t17_39();
	std::cout << "tell me why" << std::endl;


	return 0;
}




